package controllers;

import java.util.*;

import play.mvc.*;
import play.data.*;
import static play.data.Form.*;
import play.*;

import views.html.*;

import models.*;

/**
 * @author jubonnea
 *
 */
public class PasserQCM extends Controller {
	

	/**
	 * la fonction permet de lister l'ensemble des QCM
	 * @return une vue prenant en paramètre tous les Qcm présents en BD
	 */
	public static Result listeQCM() {
		return ok(listeQcm.render(Qcm.findAll()));
	}

	/**
	 * la fonction prend en paramètre un id et récupère le QCM correspondant à cet ID.
	 * elle va permettre d'afficher dans la vue tous les détails d'un QCM
	 * @return une vue prenant en paramètre l'id du QCm et le QCm correspondant
	 */
	public static Result detailsQCM(Long id) {
		Qcm QcmDetails = Qcm.findById(id);
		return ok(detailsForm.render(id, QcmDetails));
	}

	/**
	 * la fonction prend en paramètre un id et récupère le QCM correspondant à cet ID
	 * elle va permettre de commencer à passer un Qcm.
	 * @return une vue prenant en paramètre le Qcm correspondant à l'id
	 */
	public static Result debutQCM(Long id) {

		Qcm QcmDetails = Qcm.findById(id);
		return ok(debQcm.render(QcmDetails));

	}

	/**
	 * la fonction prend en paramètre un id et récupère l'Etudiant_QCM correspondant à cet ID
	 * elle va permettre d'initaliser l'Etudiant_Qcm a partir de l'id de l'étudiant en session et le QCM sélectionné
	 * @return la question suivante
	 */
	public static Result initialisationEtudiantQcm(Long id) {

		Qcm qcmRep = Qcm.findById(id);

		Etudiant_Qcm etuQcm = new Etudiant_Qcm();
		
		Etudiant et = Etudiant.findById(Long.parseLong(session("id")));
		etuQcm.setEtudiant(et);
		etuQcm.setQcm(qcmRep);
		etuQcm.save();

		return questionSuivanteQCM(etuQcm.getIdEtudiantQcm());

	}
	

	/**
	 * la fonction prend en paramètre un id et récupère l'Etudiant_QCM correspondant à cet ID
	 * elle va permettre d'afficher la question suivante tant qu'il y a des questions restantes
	 * @return la question suivante ou si c'est la fin la fct calcule la note
	 */
	public static Result questionSuivanteQCM(Long id) {
		double total = 0.0;

		Etudiant_Qcm etuQcm = Etudiant_Qcm.findById(id);

		DynamicForm dynamicForm = form().bindFromRequest();
		int numQ = Integer.parseInt(dynamicForm.get("numQ"));

		Question q = etuQcm.getQcm().getListeQuestions().get(numQ);
		Choix choix, choixEtudiant;

		Iterator<Choix> itc = q.getListeChoix().iterator();
		while (itc.hasNext()) {
			choix = (Choix) itc.next();
			if (dynamicForm.get("Choix" + choix.getIdChoix()) != null) {
				choixEtudiant = Choix.findById(Long.parseLong(dynamicForm
						.get("Choix" + choix.getIdChoix())));
				if (choixEtudiant != null) {
					etuQcm.getListeChoixEtudiant().add(choixEtudiant);
					System.out
							.println("ajout ok : " + etuQcm.toString() + "\n");
				}
			}
		}
		//on sauvegarde dans la base de données
		etuQcm.save();

		if (numQ < etuQcm.getQcm().getListeQuestions().size() - 1) {
			numQ++;
			return ok(questionQcm.render(numQ, etuQcm));
		}

		else {
			return calculNote(id);
		}
	}
	

	/**
	 * la fonction prend en paramètre un id de l'étudiant et l'id du Qcm
	 * elle affiche :
	 * 1 si la question répondue par l'étudiant est bonne, 
	 * -1 si la question répondue est fausse et 
	 * 0 si l'étudiant n'a pas répondu à la question.
	 * @return une Map contenant pour chaque question du Qcm la valeur 1, -1 ou 0
	 */
	public static Map<Question, Double> correction(Long idEtudiant, Long idQcm) {
		Map<Question, Double> repEtudiant = new HashMap<Question, Double>();
		Etudiant_Qcm etu_qcm = Etudiant_Qcm.findbyIds(idQcm, idEtudiant);
		Question question;
		Choix choix;
		int cpt_repEtudiant;
		int cpt_repJuste;

		Iterator<Question> itq = etu_qcm.getQcm().getListeQuestions()
				.iterator();
		while (itq.hasNext()) {
			question = itq.next();
			Iterator<Choix> itc = question.getListeChoix().iterator();
			cpt_repEtudiant = 0;
			cpt_repJuste = 0;
			while (itc.hasNext()) {
				choix = itc.next();
				if (choix.getEstVrai()) {
					cpt_repJuste++;
					if (etu_qcm.getListeChoixEtudiant().contains(choix)) {
						cpt_repEtudiant++;
					}
				} else {
					if (etu_qcm.getListeChoixEtudiant().contains(choix)) {
						cpt_repEtudiant = -1;
						repEtudiant.put(question, -1.0);
						break;
					}
				}
			}
			if (cpt_repEtudiant != -1) {
				if (cpt_repEtudiant == 0)
					repEtudiant.put(question, 0.00);
				else if (cpt_repEtudiant == cpt_repJuste)
					repEtudiant.put(question, 1.00);
				else if (cpt_repEtudiant != cpt_repJuste)
					repEtudiant.put(question, -1.00);
			}
		}
		return repEtudiant;
	}
	


	/**
	 * la fonction prend en paramètre un id et récupère l'Etudiant_QCM correspondant à cet ID
	 * elle va permettre de calculer la note de l'étudiant pour un Qcm à partir de la map revoyée par la fonction correction
	 * @return la question l'étudiant Qcm et la Map correction
	 */
	public static Result calculNote(Long id) {
		Double noteFinale =0.0;
		Double total = 0.0;
		Etudiant_Qcm etuQcm = Etudiant_Qcm.findById(id);
		Map<Question, Double> correction = correction(etuQcm.getEtudiant().getIdEtudiant(), etuQcm.getQcm().getIdQcm());
		
		for(Question question : etuQcm.getQcm().getListeQuestions()){
			total += etuQcm.getQcm().findQcmNiveauQuestion(question.getNiveauQuestion()).getPointPositif();
			
			//si la reponse à la question est bonne 
			if(correction.get(question)==1){
				//on ajoute les points positifs correspondant à la question
				noteFinale += etuQcm.getQcm().findQcmNiveauQuestion(question.getNiveauQuestion()).getPointPositif();
			}

			//si la reponse à la question est fausse 
			else if(correction.get(question)==-1){
				//on reture les points negatifs correspondant à la question
				noteFinale -= etuQcm.getQcm().findQcmNiveauQuestion(question.getNiveauQuestion()).getPointNegatif();	
			}	
		}
		
		//si la note est négative on la ramène à 0
		if (noteFinale < 0){
			noteFinale = 0.0;
		}
		
		//ramène la note finale sur 20 
		etuQcm.setNote((noteFinale*20)/total);
		
		etuQcm.save();
		
		return ok(finQcm.render(etuQcm, correction)); 
	}
	
	public static Result accederQcm(Long id) {
		
		Qcm qcmRep = Qcm.findById(id);
		Etudiant et = Etudiant.findById(Long.parseLong(session("id")));
		
		if(Etudiant_Qcm.findbyIds(et.getIdEtudiant(), qcmRep.getIdQcm()) != null){
			Etudiant_Qcm etuQcm = Etudiant_Qcm.findbyIds(et.getIdEtudiant(), qcmRep.getIdQcm());
			return initialisationEtudiantQcm(etuQcm.getIdEtudiantQcm());
			
		} else 
			return TODO;

//		si etud_QCm n'existe pas 
//		appeler initialisation
//		sinon
//		appeler question suivante numQ == nb de rep pour aller directement dans le else.
		
	}
	
	public static Result listeMesQCM(){
		Etudiant et = Etudiant.findById(Long.parseLong(session("id")));
		List<Qcm> listeQcm = new ArrayList<Qcm>();
		
//		if(!et.getListeqcm().isEmpty()){
//			//for(Etudiant_Qcm etuQcm :et.getListeqcm()){
//				//listeQcm.add(etuQcm.getQcm());
//			//}
//		}
//		return ok(listeMesQcm.render(listeQcm));
		return TODO;
	}

	
}